#include <linux/module.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/init.h>

static char *kbuf;

static int size = 40;

static struct kmem_cache *my_caches;

module_param(size, int, 0644);

static int __init myslab_init(void)
{
    if (size > KMALLOC_MAX_SIZE)
    {
        pr_err(" Size=%d is too big, you can't have more than %lu.\n", size, KMALLOC_MAX_SIZE);
        return -1;
    }

    my_caches = kmem_cache_create("mycaches", size, 0, SLAB_HWCACHE_ALIGN, NULL);
    if (!my_caches)
    {
        pr_err("kmem_cache_create() Failed.\n");
        return -ENOMEM;
    }

    pr_info(" Create mycaches OK.\n");

    kbuf = kmem_cache_alloc(my_caches, GFP_ATOMIC);
    if (!kbuf)
    {
        pr_err("kmem_cache_alloc Failed.\n");
        (void) kmem_cache_destroy(my_caches);
        return -1;
    }
    
    pr_info("Create a cache object success.kbuf address=0x%p\n", kbuf);

    return 0;
}

static void __exit myslab_exit(void)
{
    kmem_cache_free(my_caches, kbuf);
    pr_info("Destroy a cache object.\n");
    kmem_cache_destroy(my_caches);
    pr_info("Destroy my_caches.\n");
}

module_init(myslab_init);
module_exit(myslab_exit);

MODULE_AUTHOR("zhuguoyin");
MODULE_LICENSE("GPL");
